/*-
  use bamp::ApiParser;
  use bamp::CApiGen;
  
  my $api = bamp::ApiParser->new("bamp.api", CLASSNAME);
  my $c   = bamp::CApiGen->new($api);
  die "API parsing failed" if ${$api}{errors};

  my $class      = CLASSNAME; $class =~ s/::/_/g;
  my $incl_guard = "__BAMP_".uc($class)."_H__";
  my $struct     = lc($class);
  my $shortname  = $struct;
  $shortname =~ s/\w+?_//;

  my @includes = ();
  my @parents  = ();
  
  for my $p ($api->parents()) {
    $p =~ s/\w+:://;
    $p = lc($p);
    push(@includes, "bamp/".$p."_api.h");
    push(@parents, $p);
  }

  push(@includes,"bamp/rc.h", "stddef.h");

*/
/*
 * /*= $c->header() */
 */

#ifndef /*$incl_guard*/
#define /*$incl_guard*/

/*- for ($api->includes("C", @includes)) { */
#include </*$_*/>
/*- } */

#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
    /*-
      for my $m ($api->methods()) {
      my $n = $c->meth_name($m);
      my @a;
      push (@a, "const void* ctx") if ${$m}{const};
      push (@a, "void* ctx")       unless ${$m}{const};
      push (@a, $c->args($m));
    */
    bamp_rc (*/*$n*/)(/*+join(', ', @a)*/);
    /*- } */
    /*- 
      for my $parent ($api->parents()) {
      my @methods = $api->class_methods($parent);
      if ($#methods >= 0) {
      my $p = lc($parent);
      $p =~ s/\w+:://;
    */
    bamp_/*$p*/_func_t /*$p*/;
    /*- } } */
    
} /*$struct*/_func_t;


typedef struct
{
    void*  __ctx;  /// Pointer to the implementer object
    size_t __refs; /// Reference count
    bamp_rc (*__dctor)(void* ctx);             /// Destructor implementation
    bamp_rc (*__clone)(void** dst, void* src); /// Object copy implementation
    /*$struct*/_func_t f; /// Function pointers

} /*$struct*/;


/**
 * Allocate and initialize a /*$struct*/ with NULL pointers and a reference
 * count of 1.
 */
bamp_rc /*$struct*/_new(/*$struct*/** /*$shortname*/);

/**
 * Increase the reference count of a /*$struct*/ object.
 */
bamp_rc /*$struct*/_ref(/*$struct*/* /*$shortname*/);

/**
 * Decrease the reference count of a /*$struct*/ object. Free its
 * underlying object if the reference count has reached zero.
 */
bamp_rc /*$struct*/_unref(/*$struct*/* /*$shortname*/);

/**
 * Create a new, deep copy of the object held by the structure.
 * The new object will have a reference count of 1.
 */
bamp_rc /*$struct*/_clone(void** dst, /*$struct*/* src);
    
/*-
  for my $m ($api->all_methods()) {
  my $n = $struct."_".$c->meth_name($m);
  my @a;
  push (@a, "const $struct* $shortname") if ${$m}{const};
  push (@a, "$struct* $shortname")       if !${$m}{const};
  push (@a, $c->args($m));
*/
bamp_rc /*$n*/(/*+join(', ', @a)*/);
/*- } */


#ifdef __cplusplus
}
#endif

#endif // /*$incl_guard*/
